package com.ctcemti.mdm.project.sys.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import com.ctcemti.mdm.common.util.BatchOperationUtils;
import com.ctcemti.mdm.common.util.ExcelExportStylerImpl;
import com.ctcemti.mdm.common.util.ExcelParseUtils;
import com.ctcemti.mdm.common.util.JWTUtil;
import com.ctcemti.mdm.project.common.excelverifyhandler.ExcelVerifyHandlerToEBSTree;
import com.ctcemti.mdm.project.sys.dao.ResEntElementTreeMapper;
import com.ctcemti.mdm.project.sys.entity.ResEntElementTree;
import com.ctcemti.mdm.project.sys.service.IResEntElementTreeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;

@Service
@Slf4j
public class ResEntElementTreeServiceImpl implements IResEntElementTreeService {


    @Autowired
    private ResEntElementTreeMapper resEntElementTreeMapper;


    @Value("${ctcemti.errorfilepath}")
    private String errorfilepath;
    /**
     * @param resEntElementTree
     * @return
     * @Author pzw
     * @Description 查询企业级ebs树
     * @Date 11:39 2019/7/22
     * @Param
     */
    @Override
    public List<ResEntElementTree> selectAllResEntElementTree(ResEntElementTree resEntElementTree) {
        List<ResEntElementTree> resEntElementTrees=null;
        switch (resEntElementTree.getType()) {
            case "queryHierarchy":
                resEntElementTrees = resEntElementTreeMapper.selectChildsByHierarchy(resEntElementTree);
                break;

            case "async":
                //异步加载
                Example example = new Example(ResEntElementTree.class);
                Example.Criteria type = example.createCriteria();
                if (resEntElementTree.getParentId() != null && !resEntElementTree.getParentId().equals("0")) {
                    type.andEqualTo("parentId", resEntElementTree.getParentId());
                }
                resEntElementTrees = resEntElementTreeMapper.selectByExample(example);
                break;

            case "queryName":
                Boolean nameFlag = resEntElementTree.getName() != null && resEntElementTree.getName() != "";
                if (nameFlag) {
                    resEntElementTree.setName("%" + resEntElementTree.getName() + "%");
                    resEntElementTrees = resEntElementTreeMapper.selectAllResEntElementTree(resEntElementTree);
                }
                break;
        }
        //resultToEasyUI.setRows(resEntElementTrees);
        //异步加载不需要设置state
        if("async".equals(resEntElementTree.getType())){
            return resEntElementTrees;
        }
        Map<String, String> map = new HashMap<>();
        for (ResEntElementTree entElementTree : resEntElementTrees) {
            if(entElementTree.getHierarchy()==1){
                entElementTree.set_parentId(null);
            }
            map.put(entElementTree.getParentId(),"1");
        }
        for (ResEntElementTree entElementTree : resEntElementTrees) {
            if(map.get(String.valueOf(entElementTree.getId()))==null){
                entElementTree.setState(false);
            }else{
                entElementTree.setState(true);
            }
        }
        return resEntElementTrees;
    }

    /**
     * @param resEntElementTree
     * @return
     * @Author pzw
     * @Description 通过id查询实体
     * @Date 11:39 2019/7/22
     * @Param
     */
    @Override
    public ResEntElementTree queryResEntElementTreeByID(ResEntElementTree resEntElementTree) {
        return resEntElementTreeMapper.queryResEntElementTreeByID(resEntElementTree);
    }

    /**
     * @param resEntElementTree
     * @return
     * @Author pzw
     * @Description 插入
     * @Date 11:39 2019/7/22
     * @Param
     */
    @Override
    @Transactional
    public int insertResEntElementTreeByID(ResEntElementTree resEntElementTree) {
        return resEntElementTreeMapper.insertSelective(resEntElementTree);
    }

    /**
     * @param resEntElementTree
     * @return
     * @Author pzw
     * @Description 修改
     * @Date 11:39 2019/7/22
     * @Param
     */
    @Override
    @Transactional
    public int updateResEntElementTreeByID(ResEntElementTree resEntElementTree) {
        return resEntElementTreeMapper.updateResEntElementTreeByID(resEntElementTree);
    }

    /**
     * @param ids
     * @return
     * @Author pzw
     * @Description  删除 先删除关系，在删除ebs
     * @Date 11:39 2019/7/22
     * @Param
     */
    @Override
    @Transactional
    public int deleteResEntElementTreeByID(Integer[] ids) {
        List<ResEntElementTree> list=resEntElementTreeMapper.selectEBSByIds(ids);
        Example example = new Example(ResEntElementTree.class);
        Example.Criteria criteria = example.createCriteria();
        for (ResEntElementTree resEntElementTree : list) {
            criteria.orLike("ebs",resEntElementTree.getEbs()+"%");
        }
        resEntElementTreeMapper.deleteByExample(example);//删除项目及ebs
        return resEntElementTreeMapper.deleteRelMethodByEbs(list);
    }

    /**
     * @param resEntElementTree
     * @return
     * @Author pzw
     * @Description 移动
     * @Date 11:39 2019/7/22
     * @Param
     */
    @Override
    @Transactional
    public int moveResEntElementTree(ResEntElementTree resEntElementTree) {
        resEntElementTreeMapper.moveResEntElementTree(resEntElementTree);
        return resEntElementTreeMapper.moveResEntElementTreeMethod(resEntElementTree);
    }

    /**
     * @param resEntElementTree
     * @return
     * @Author pzw
     * @Description 同步工法库(触发器实现 关系表插入、删除修改企业ebs数据)
     * @Date 11:39 2019/7/22
     * @Param
     */
    @Override
    public int syncResEntElementTree(ResEntElementTree resEntElementTree) {
        resEntElementTreeMapper.deleteElementsMethodsByDisciplineId(resEntElementTree);
        return resEntElementTreeMapper.syncResEntElementTree(resEntElementTree);
    }

    /**
     * @param multipartFile
     * @param disciplinesId
     * @param response
     * @return
     * @Author
     * @Description 导入文件
     * @Date 11:39 2019/7/22
     * @Param
     */
    @Override
    @Transactional
    public Map<String, Object> uploadFile(MultipartFile multipartFile, String disciplinesId, HttpServletResponse response,HttpServletRequest request) throws IOException {
        Map<String,Object> resultMap = new HashMap<String,Object>();
        ExcelImportResult<ResEntElementTree> excelImportResult = ExcelParseUtils.
                importExcelMore(multipartFile,0,1,ResEntElementTree.class,new ExcelVerifyHandlerToEBSTree(resEntElementTreeMapper));
        boolean flag = true;
        if(excelImportResult.getFailList().size()>0){//验证失败，重新写入excel，并保存
            String filename = UUID.randomUUID().toString();//获取新的文件名
            File folder = new File(errorfilepath);//文件夹
            if(!folder.exists()){
                boolean mkFlag = folder.mkdirs();
                if (mkFlag) {
                    log.error("未找到上传文件夹，新建文件夹");
                }
            }
            FileOutputStream fos = null;
            try {
                //fileOutputStream = new FileOutputStream(file);
                //excelImportResult.getWorkbook().write(fileOutputStream);
                List<ResEntElementTree> slist = excelImportResult.getList();//获取所有成功项
                List<ResEntElementTree> flist = excelImportResult.getFailList();//获取所有失败项
                slist.addAll(flist);
                Collections.sort(slist);
                ExportParams exportParams = new ExportParams(null,null,"错误列表");
                exportParams.setStyle(ExcelExportStylerImpl.class);
                Workbook workbook = ExcelExportUtil.exportExcel(exportParams,ResEntElementTree.class, slist);
                fos = new FileOutputStream(errorfilepath+"/"+filename+".xls");
                workbook.write(fos);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                if(fos!=null){
                    fos.close();
                }
            }
            flag = false;
            resultMap.put("flag",flag);
            resultMap.put("filecode",filename);

        }else{
            //成功验证，准备导入数据
            List<ResEntElementTree> list = excelImportResult.getList();
            String loginId = JWTUtil.getLoginId(request.getHeader("Authorization"));
            for (ResEntElementTree resEntElementTree : list) {
                resEntElementTree.setCreator(loginId);
            }
            //获取父级关系
            analyticalRelationships(list,disciplinesId);
            //工艺工法库插入
            BatchOperationUtils<ResEntElementTree> batchOperationUtils = new BatchOperationUtils();
            batchOperationUtils.batchOperation(list, 200,var->resEntElementTreeMapper.insertBatch(var));
            resEntElementTreeMapper.updateParentIDByUUID(disciplinesId);
            resultMap.put("flag",flag);
        }
        return resultMap;
    }

    /**
     * @param resEntElementTree
     * @return
     * @Author Ebs编码是否存在
     * @Description 移动
     * @Date 11:39 2019/7/22
     * @Param
     */
    @Override
    public int queryEBSCodeHasExist(ResEntElementTree resEntElementTree) {

        return resEntElementTreeMapper.queryEBSCodeHasExist(resEntElementTree);
    }

    /**
     * @param resEntElementTree
     * @return
     * @Author 获取最大层级
     * @Description 移动
     * @Date 11:39 2019/7/22
     * @Param
     */
    @Override
    public int getMaxHierarchy(ResEntElementTree resEntElementTree) {
        return resEntElementTreeMapper.getMaxHierarchy(resEntElementTree);
    }

    /**
     * 通过层级遍历父子关系（二叉树前序遍历 确定父级子关系）
     * @param list
     * @return
     */
    private List<ResEntElementTree> analyticalRelationships(List<ResEntElementTree> list,String disciplinesId){
        ResEntElementTree tmp=null;
        for (int i=0;i<list.size();i++) {
            String uuid = UUID.randomUUID().toString();
            ResEntElementTree start=list.get(i);
            start.setUuid(uuid);
            start.setParentId("0");
            start.setDisciplinesId(disciplinesId);
            if("2".equals(list.get(i).getHierarchy())){
                tmp=list.get(i);
            }
            if("3".equals(list.get(i).getHierarchy())&&tmp!=null){
                start.setParentId(tmp.getUuid());
                continue;
            }
            for (int j=i-1;j>=0;j--){
                ResEntElementTree parent=list.get(j);
                if("3".equals(parent.getHierarchy())){

                }
                if(parent.getHierarchy()==(start.getHierarchy()-1)){
                    start.setParentId(parent.getUuid());
                    break;
                }
            }
        }
        return list;
    }

}
